// 百度实时语音识别WebSocket服务
export interface RealtimeSpeechConfig {
    apiKey: string;
    secretKey: string;
}

export interface RealtimeSpeechResult {
    success: boolean;
    text?: string;
    error?: string;
    isFinal?: boolean; // 是否为最终结果
}

export interface RealtimeSpeechCallbacks {
    onResult?: (result: RealtimeSpeechResult) => void;
    onError?: (error: string) => void;
    onConnected?: () => void;
    onDisconnected?: () => void;
}

class BaiduRealtimeSpeechService {
    private config: RealtimeSpeechConfig;
    private websocket: WebSocket | null = null;
    private accessToken: string | null = null;
    private tokenExpireTime: number = 0;
    private callbacks: RealtimeSpeechCallbacks = {};
    private isConnected: boolean = false;
    private cuid: string;
    private audioDataSent: boolean = false;

    constructor(config: RealtimeSpeechConfig) {
        this.config = config;
        this.cuid = 'webclient001';
    }

    // 获取百度访问令牌
    private async getAccessToken(): Promise<string> {
        try {
            // 如果已有有效token，直接返回
            if (this.accessToken && Date.now() < this.tokenExpireTime) {
                return this.accessToken;
            }

            console.log('🔑 开始获取访问令牌...');
            const response = await fetch('/baidu/oauth/2.0/token', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: new URLSearchParams({
                    grant_type: 'client_credentials',
                    client_id: this.config.apiKey,
                    client_secret: this.config.secretKey
                })
            });

            console.log('🔑 访问令牌响应状态:', response.status);
            if (!response.ok) {
                throw new Error(`HTTP ${response.status}: ${response.statusText}`);
            }

            const data = await response.json();
            console.log('🔑 访问令牌响应数据:', data);

            if (data.access_token) {
                this.accessToken = data.access_token;
                this.tokenExpireTime = Date.now() + (data.expires_in - 60) * 1000; // 提前1分钟过期
                console.log('✅ 访问令牌获取成功');
                return this.accessToken!;
            } else {
                console.error('❌ 访问令牌获取失败:', data);
                throw new Error(data.error_description || data.error || '获取访问令牌失败');
            }
        } catch (error) {
            console.error('获取访问令牌失败:', error);
            throw error;
        }
    }

    // 开始实时语音识别
    async startRecognition(callbacks: RealtimeSpeechCallbacks): Promise<void> {
        try {
            this.callbacks = callbacks;
            this.audioDataSent = false; // 重置音频数据发送标志

            // 根据百度API文档，WebSocket连接不需要访问令牌
            console.log('使用API Key和Secret Key进行WebSocket连接');

            // 生成随机sn参数
            const sn = this.generateSn();

            // 建立WebSocket连接
            const wsUrl = `wss://vop.baidu.com/realtime_asr?sn=${sn}`;
            console.log('连接WebSocket:', wsUrl);
            console.log('SN参数:', sn);

            this.websocket = new WebSocket(wsUrl);

            this.websocket.onopen = () => {
                console.log('✅ WebSocket连接已建立');
                this.isConnected = true;
                this.callbacks.onConnected?.();

                // 延迟发送开始参数帧，确保连接稳定
                setTimeout(() => {
                    this.sendStartFrame();
                }, 100);
            };

            this.websocket.onmessage = (event) => {
                try {
                    const data = JSON.parse(event.data);
                    console.log('收到WebSocket消息:', data);

                    if (data.type === 'RESULT') {
                        // 处理识别结果
                        const result: RealtimeSpeechResult = {
                            success: true,
                            text: data.result?.[0] || '',
                            isFinal: data.is_final || false
                        };
                        this.callbacks.onResult?.(result);
                    } else if (data.type === 'ERROR') {
                        // 处理错误
                        const error = data.error || '语音识别错误';
                        this.callbacks.onError?.(error);
                    }
                } catch (error) {
                    console.error('解析WebSocket消息失败:', error);
                    this.callbacks.onError?.('解析识别结果失败');
                }
            };

            this.websocket.onclose = (event) => {
                console.log('❌ WebSocket连接已关闭:', event.code, event.reason);
                this.isConnected = false;

                // 根据关闭代码提供更详细的错误信息
                let errorMessage = 'WebSocket连接已关闭';
                if (event.code === 1005) {
                    errorMessage = 'WebSocket连接异常关闭，可能是参数错误或网络问题';
                } else if (event.code === 1006) {
                    errorMessage = 'WebSocket连接异常关闭，请检查网络连接';
                } else if (event.code === 1000) {
                    errorMessage = 'WebSocket正常关闭';
                } else {
                    errorMessage = `WebSocket连接关闭，代码: ${event.code}`;
                }

                console.error('关闭原因:', errorMessage);
                this.callbacks.onError?.(errorMessage);
                this.callbacks.onDisconnected?.();
            };

            this.websocket.onerror = (error) => {
                console.error('❌ WebSocket错误:', error);
                this.isConnected = false;
                this.callbacks.onError?.('WebSocket连接错误');
            };

        } catch (error) {
            console.error('启动实时语音识别失败:', error);
            this.callbacks.onError?.(error instanceof Error ? error.message : '启动识别失败');
        }
    }

    // 发送开始参数帧
    private sendStartFrame(): void {
        if (!this.websocket || this.websocket.readyState !== WebSocket.OPEN) {
            console.error('WebSocket未连接，无法发送开始帧');
            return;
        }

        const startFrame = {
            type: "START",
            data: {
                appid: this.config.apiKey, // API Key作为字符串使用
                appkey: this.config.secretKey, // 根据API文档，需要包含appkey
                dev_pid: 15372, // 中文普通话，加强标点
                cuid: this.cuid,
                format: "pcm",
                sample: 16000
            }
        };

        console.log('📤 发送开始参数帧:', startFrame);
        console.log('📤 开始参数帧JSON:', JSON.stringify(startFrame));
        console.log('📤 API Key类型:', typeof this.config.apiKey, '值:', this.config.apiKey);
        try {
            this.websocket.send(JSON.stringify(startFrame));
            console.log('✅ 开始参数帧发送成功');
        } catch (error) {
            console.error('❌ 发送开始参数帧失败:', error);
            this.callbacks.onError?.('发送开始参数帧失败');
        }
    }

    // 发送音频数据
    sendAudioData(audioData: ArrayBuffer): void {
        if (!this.websocket || this.websocket.readyState !== WebSocket.OPEN) {
            console.error('WebSocket未连接，无法发送音频数据');
            return;
        }

        // 将ArrayBuffer转换为Base64
        const base64 = this.arrayBufferToBase64(audioData);

        const audioFrame = {
            type: "AUDIO",
            data: base64
        };

        // 只在第一次发送时打印日志，避免日志过多
        if (!this.audioDataSent) {
            console.log('🎵 开始发送音频数据，数据大小:', audioData.byteLength, 'bytes');
            this.audioDataSent = true;
        }

        this.websocket.send(JSON.stringify(audioFrame));
    }

    // 停止识别
    stopRecognition(): void {
        if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
            // 发送结束帧
            const finishFrame = {
                type: "FINISH"
            };
            this.websocket.send(JSON.stringify(finishFrame));
        }

        this.closeConnection();
    }

    // 关闭连接
    closeConnection(): void {
        if (this.websocket) {
            this.websocket.close();
            this.websocket = null;
        }
        this.isConnected = false;
    }

    // 生成随机sn参数
    private generateSn(): string {
        const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-';
        let result = '';
        for (let i = 0; i < 19; i++) {
            if (i === 4 || i === 9 || i === 14) {
                result += '-';
            } else {
                result += chars.charAt(Math.floor(Math.random() * chars.length));
            }
        }
        return result;
    }

    // 将ArrayBuffer转换为Base64
    private arrayBufferToBase64(buffer: ArrayBuffer): string {
        const bytes = new Uint8Array(buffer);
        let binary = '';
        for (let i = 0; i < bytes.byteLength; i++) {
            binary += String.fromCharCode(bytes[i]);
        }
        return btoa(binary);
    }

    // 检查是否已连接
    isRecognitionActive(): boolean {
        return this.isConnected && this.websocket?.readyState === WebSocket.OPEN;
    }

    // 清除缓存的访问令牌
    clearAccessToken(): void {
        this.accessToken = null;
        this.tokenExpireTime = 0;
    }

    // 测试访问令牌是否有效
    async testAccessToken(): Promise<boolean> {
        try {
            const token = await this.getAccessToken();
            console.log('✅ 访问令牌测试成功:', token ? '有效' : '无效');
            console.log('访问令牌长度:', token?.length);
            console.log('访问令牌前20位:', token?.substring(0, 20));
            return !!token;
        } catch (error) {
            console.error('❌ 访问令牌测试失败:', error);
            return false;
        }
    }

    // 测试WebSocket连接
    async testWebSocketConnection(): Promise<boolean> {
        try {
            await this.getAccessToken();
            if (!this.accessToken) {
                console.error('❌ 无法获取访问令牌');
                return false;
            }

            const sn = this.generateSn();
            const wsUrl = `wss://vop.baidu.com/realtime_asr?sn=${sn}&access_token=${this.accessToken}`;
            console.log('测试WebSocket连接:', wsUrl);

            return new Promise((resolve) => {
                const testWs = new WebSocket(wsUrl);
                const timeout = setTimeout(() => {
                    testWs.close();
                    resolve(false);
                }, 5000);

                testWs.onopen = () => {
                    console.log('✅ WebSocket测试连接成功');
                    clearTimeout(timeout);
                    testWs.close();
                    resolve(true);
                };

                testWs.onerror = (error) => {
                    console.error('❌ WebSocket测试连接失败:', error);
                    clearTimeout(timeout);
                    resolve(false);
                };

                testWs.onclose = (event) => {
                    console.log('WebSocket测试连接关闭:', event.code, event.reason);
                    clearTimeout(timeout);
                    resolve(false);
                };
            });
        } catch (error) {
            console.error('❌ WebSocket测试失败:', error);
            return false;
        }
    }
}

// 创建服务实例
export const baiduRealtimeSpeechService = new BaiduRealtimeSpeechService({
    apiKey: 'LUTt6BTb7akmk7OllOObiW3q',
    secretKey: 'VmxO3x1pxDOEgBmusvXIc2Ufil6bvTgy'
});

export default baiduRealtimeSpeechService;
